package examples.rrc;

import java.lang.System;
//import MT.*;

class Gate extends TimeThread
{
    RRC rrc;

    int cross_length , gate_length, gate_center_x, gate_center_y; 
    Signal lower; 
    Signal raise ;

    int ni,gamma,delta,ip;

    Gate(RRC r)
    {	
		rrc = r;
		cross_length = rrc.cross_length;
		gate_length = rrc.gate_length;
		gate_center_x = rrc.gate_center_x;
		gate_center_y = rrc.gate_center_y;
		ni = r.ni;
		ip = r.ip;
		delta = r.delta;
		gamma = r.gamma;
		time_unit = rrc.time_unit;
		time_tolerant = rrc.time_tolerant;
		lower = new Signal();
		raise = new Signal();
    }

    public void run()
    {
		int down_degree = 0; 	// 0 means up.  gamma means down. 
		while(true)
		{
			if( !lower.value) 	// Waiting for lower signal
			{
				lower.receive();
				set_calc_start();
			}
			else 				// Already had lower signal during gu()
			{
				lower.value = false;
			}

			gd_aux(down_degree);
			down_degree = gu();
		}

    }

	public void gd_aux(int j)
	{
		gd(j);
		raise.receive();
		set_calc_start();
	}



    private void gd(int j)
    {
		int up_degree;
		double angle_per_unit_time = (Math.PI/2) * (
		((gamma-j)/(double)gamma)  /(double)gamma); 
		double start_angle = (Math.PI/2.0) * (j/(double)gamma);

		for(int i=1; i <= gamma; i++)
		{
			//Update gate's end's x position at every 1 time unit.
			rrc.gate_end_x = (int)(gate_center_x 
			- Math.sin(start_angle + angle_per_unit_time * i ) * gate_length);
			rrc.gate_end_y = (int)(gate_center_y 
			- Math.cos(start_angle + angle_per_unit_time * i ) * gate_length); 
			// 1 time unit advance
			try {Thread.sleep(rrc.time_unit-get_calc_time() - time_tolerant);}
			catch(InterruptedException e){}
			catch(IllegalArgumentException e){}
			
			set_calc_start();	
		}
		rrc.showStatus("Gate is completely DOWN!!");
    }// End of void gd()

    public int gu()
    {
		for(int i=1; i <= gamma; i++)
		{
			if( lower.value ) 
			{
				return (gamma- (i-1));
			}

			rrc.gate_end_x = (int)(gate_center_x 
				- Math.cos( (double)(i*Math.PI/2.0) /(double)gamma) 
					* gate_length);
			rrc.gate_end_y = (int)(gate_center_y 
				- Math.sin( (double)(i*Math.PI/2.0)/(double)gamma) 
					* gate_length);
			
			// 1 time unit advance
			try{Thread.sleep(rrc.time_unit- get_calc_time() - time_tolerant);}
			catch(InterruptedException e){}
			catch(IllegalArgumentException e){}

			set_calc_start();

		}
		rrc.showStatus("Gate is completely UP!!!"); 
		return 0;
    }
}// End of class Gate


